﻿namespace BadHabit.WPFTools
{
    using System;
    using System.Windows;
    using System.Windows.Controls.Primitives;
    using System.Windows.Input;

    public class SelectionBehavior
    {
        public static DependencyProperty SelectionChangedProperty = DependencyProperty.RegisterAttached("SelectionChanged", typeof(ICommand), typeof(SelectionBehavior), new UIPropertyMetadata(SelectionBehavior.SelectedItemChanged));

        public static void SetSelectionChanged(DependencyObject target, ICommand value)
        {
            target.SetValue(SelectionBehavior.SelectionChangedProperty, value);
        }

        private static void SelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            Selector element = target as Selector;
            
            if (element == null)
            {
                throw new InvalidOperationException("This behavior can be attached to Selector item only.");
            }

            if ((e.NewValue != null) && (e.OldValue == null))
            {
                element.SelectionChanged += SelectionChanged;
            }
            else if ((e.NewValue == null) && (e.OldValue != null))
            {
                element.SelectionChanged -= SelectionChanged;
            }
        }
        
        private static void SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            UIElement element = (UIElement)sender;
            ICommand command = (ICommand)element.GetValue(SelectionBehavior.SelectionChangedProperty);
            command.Execute(((Selector)sender).SelectedValue);
        }

        public static DependencyProperty DropDownClosedProperty = DependencyProperty.RegisterAttached("DropDownClosed", typeof(ICommand), typeof(SelectionBehavior), new UIPropertyMetadata(SelectionBehavior.ComboBoxDropDownClosed));

        public static void SetDropDownClosed(DependencyObject target, ICommand value)
        {
            target.SetValue(SelectionBehavior.DropDownClosedProperty, value);
        }
        
        private static void ComboBoxDropDownClosed(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            ComboBox element = target as ComboBox;
            if (element == null)
            {
                throw new InvalidOperationException("This behavior can be attached to ComboBox item only.");
            }

            if ((e.NewValue != null) && (e.OldValue == null))
            {
                element.DropDownClosed += DropDownClosed;
            }
            else if ((e.NewValue == null) && (e.OldValue != null))
            {
                element.DropDownClosed -= DropDownClosed;
            }
        }

        private static void DropDownClosed(object sender, EventArgs e)
        {
            UIElement element = (UIElement)sender;
            ICommand command = (ICommand)element.GetValue(SelectionBehavior.DropDownClosedProperty);
            command.Execute(((Selector)sender).SelectedValue);
        }
    }
}
